package com.siyoumi.app.modules.fun_mall.service;

import com.siyoumi.app.entity.FunMallPrize;
import com.siyoumi.app.entity.SysPrize;
import com.siyoumi.app.entity.SysPrizeSet;
import com.siyoumi.app.entity.SysStock;
import com.siyoumi.app.modules.fun.service.SvcFun;
import com.siyoumi.app.modules.fun_mall.vo.FunMallGet;
import com.siyoumi.app.modules.fun_mall.vo.VaFunMallPrize;
import com.siyoumi.app.modules.prize.service.SvcSysPrize;
import com.siyoumi.app.modules.prize.service.SvcSysPrizeSet;
import com.siyoumi.app.modules.prize.service.SvcSysPrizeSetAdmin;
import com.siyoumi.app.sys.service.prize.PrizeSend;
import com.siyoumi.app.service.FunMallPrizeService;
import com.siyoumi.app.service.SysStockService;
import com.siyoumi.component.XApp;
import com.siyoumi.component.XSpringContext;
import com.siyoumi.component.http.InputData;
import com.siyoumi.component.http.XHttpContext;
import com.siyoumi.exception.EnumSys;
import com.siyoumi.mybatispuls.JoinWrapperPlus;
import com.siyoumi.service.IWebService;
import com.siyoumi.util.XDate;
import com.siyoumi.util.XReturn;
import com.siyoumi.util.XStr;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

//积分商城-商品
@Service
@Slf4j
public class SvcFunMallPrize
        implements IWebService {
    static public SvcFunMallPrize getBean() {
        return XSpringContext.getBean(SvcFunMallPrize.class);
    }

    static public FunMallPrizeService getApp() {
        return FunMallPrizeService.getBean();
    }

    public XReturn valid(String goodsId) {
        FunMallPrize entityGoods = getApp().loadEntity(goodsId);
        if (entityGoods == null) {
            return EnumSys.ERR_VAL.getR("商品ID异常");
        }

        if (XDate.now().isBefore(entityGoods.getFprize_begin_date())) {
            return XReturn.getR(20019, "商品未开始");
        }

        if (XDate.now().isAfter(entityGoods.getFprize_end_date())) {
            return XReturn.getR(20022, "商品已结束");
        }

        if (entityGoods.getFprize_enable() != 1) {
            return XReturn.getR(20032, "商品下架中");
        }

        SysStock entityStock = SysStockService.getBean().getEntityBySrc(entityGoods.getFprize_id());
        if (entityStock.getStock_count_left() <= 0) {
            return XReturn.getR(20042, "库存为0");
        }


        return EnumSys.OK.getR();
    }

    /**
     * 能否兑换
     *
     * @param vo
     */
    public XReturn canGet(FunMallGet vo) {
        XReturn r = valid(vo.getGoods_id());
        if (r.err()) {
            return r;
        }

        FunMallPrize entityGoods = getApp().loadEntity(vo.getGoods_id());
        Long fun = SvcFun.getBean().getFun(vo.getOpenid());
        if (fun < entityGoods.getFprize_fun()) {
            return XReturn.getR(20052, "积分不足");
        }

        Long userGetTotal = userGetTotal(vo.getGoods_id());
        if (userGetTotal >= entityGoods.getFprize_get_total()) {
            return XReturn.getR(20062, "商品只能兑换" + entityGoods.getFprize_get_total());
        }

        return r;
    }

    /**
     * 兑换
     */
    public XReturn get(FunMallGet vo) {
        XReturn r = canGet(vo);
        if (r.err()) {
            return r;
        }

        log.info("goods_id: {}", vo.getGoods_id());
        return XApp.getTransaction().execute(status -> {
            FunMallPrize entityGoods = getApp().loadEntity(vo.getGoods_id());

            log.info("扣库存");
            SysStockService.getBean().subStock(entityGoods.getKey(), 1L);

            log.info("扣积分");
            String key = XStr.format("{0}|{1}", entityGoods.getKey(), XDate.toDateTimeString());
            SvcFun.getBean().add(key, vo.getOpenid(), entityGoods.getKey(), "fun_mall", entityGoods.getFprize_fun(), "商品兑换");

            log.info("发奖");
            SysPrizeSet entityPrizeSet = SvcSysPrizeSet.getBean().getEntityByIdSrc(entityGoods.getKey());
            PrizeSend prizeSend = PrizeSend.getBean(entityPrizeSet);
            return prizeSend.send(key, vo.getOpenid());
        });
    }

    /**
     * 用户兑换总数
     *
     * @param goodsId
     */
    public Long userGetTotal(String goodsId) {
        JoinWrapperPlus<SysPrize> query = SvcSysPrize.getBean().listQuery();
        query.eq("prize_id_src", goodsId)
                .eq("prize_app_id", "fun_mall");

        return SvcSysPrize.getApp().count(query);
    }

    public JoinWrapperPlus<FunMallPrize> listQuery() {
        return listQuery(InputData.getIns());
    }

    /**
     * select
     *
     * @return query
     */
    public JoinWrapperPlus<FunMallPrize> listQuery(InputData inputData) {
        String name = inputData.input("name");
        String groupId = inputData.input("group_id");

        JoinWrapperPlus<FunMallPrize> query = getApp().join();
        query.join(SysPrizeSet.table(), "pset_id_src", "fprize_id");
        query.eq("fprize_x_id", XHttpContext.getX());
        getApp().addQueryAcc(query);

        //排序
        query.orderByAsc("fprize_order")
                .orderByDesc("fprize_id");
        if (XStr.hasAnyText(name)) { //名称
            query.like("pset_name", name);
        }
        if (XStr.hasAnyText(groupId)) { //分组
            query.like("fprize_group_id", groupId);
        }

        return query;
    }


    public XReturn edit(InputData inputData, VaFunMallPrize vo) {
        List<String> ignoreField = new ArrayList<>();
        if (inputData.isAdminEdit()) {
            ignoreField.add("fprize_acc_id");
        }

        return XApp.getTransaction().execute(status -> {
            XReturn r = SvcFunMallPrize.getApp().saveEntity(inputData, vo, true, ignoreField);
            if (r.err()) {
                return r;
            }

            FunMallPrize entity = r.getData("entity");
            SvcSysPrizeSetAdmin.getIns(true).editSave(entity.getFprize_id(), "fun_mall", vo);

            return r;
        });
    }

    /**
     * 删除
     */
    @SneakyThrows
    @Transactional(propagation = Propagation.MANDATORY)
    public XReturn delete(List<String> ids) {
        XReturn r = XReturn.getR(0);

        getApp().delete(ids);

        return r;
    }
}
